package com.git.hui.yinshua.biz.common.oss.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.git.hui.yinshua.api.model.ReqInfoContext;
import com.git.hui.yinshua.biz.common.oss.ImageUploader;
import com.git.hui.yinshua.biz.common.wx.WxUserHelper;
import com.git.hui.yinshua.biz.util.Md5Util;
import com.git.hui.yinshua.biz.util.net.HttpRequestHelper;
import com.git.hui.yinshua.common.DateUtil;
import com.git.hui.yinshua.common.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Map;

/**
 * 腾讯云服务图片存储功能
 * <p>
 * 官方文档：
 * 上传：https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html
 * 下载：https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDownloadFile.html
 *
 * @author YiHui
 * @date 2024/6/21
 */
@Slf4j
@ConditionalOnExpression(value = "#{'tx'.equals(environment.getProperty('image.oss.type'))}")
@Component
public class TxCloudOssWrapper implements ImageUploader {

    private static final String UPLOAD_API = "https://api.weixin.qq.com/tcb/uploadfile?access_token=%s";

    private static final String DOWNLOAD_API = "https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=%s";

    @Value("${wx.cloudEnv}")
    private String env;
    @Autowired
    private WxUserHelper wxUserHelper;

    @Value("${wx.imgHost:}")
    private String imgHost;


    /**
     * 获取文件上传的路径
     *
     * @return
     */
    private String genImgFilePath(byte[] bytes, String fileType) {
        String path;
        Integer uid = ReqInfoContext.getReqInfo().getUserId();
        if (uid == null) {
            uid = 0;
            // 用户的图片，按月进行归档
            path = DateUtil.getToday();
        } else {
            // 非用户的图片，按天进行归档
            path = DateUtil.getThisMonth();
        }
        String fileName = Md5Util.encode(bytes);
        return "ys/" + uid + "/" + path + "/" + fileName + "." + fileType;
    }

    @Override
    public String upload(InputStream input, String fileType) {
        String url = String.format(UPLOAD_API, wxUserHelper.getAccessToken());
        try {
            byte[] bytes = StreamUtils.copyToByteArray(input);
            String upFileName = this.genImgFilePath(bytes, fileType);

            String uploadAns = HttpRequestHelper.postJson(url, MapUtil.newMap("env", env, "path", upFileName), String.class);
            JSONObject upObj = JSONObject.parseObject(uploadAns);
            String uploadUrl = upObj.getString("url");

            String res = HttpRequestHelper.uploadTxCloudByOk(uploadUrl, upFileName,
                    bytes,
                    upFileName,
                    upObj.getString("authorization"),
                    upObj.getString("token"),
                    upObj.getString("cos_file_id"));
            log.info("图片上传之后返回结果: {}", res);

            String upFileHttpUrl = getFileHttpUrl(upObj.getString("file_id"), upFileName);
            // 返回文件访问的绝对地址
            return upFileHttpUrl;
        } catch (Exception e) {
            log.error("upload image error response! uri:{}", env, e);
            return null;
        }
    }

    @Override
    public boolean uploadIgnore(String fileUrl) {
        return fileUrl.startsWith("http") || fileUrl.startsWith("cloud:");
    }


    /**
     * 云图片换取 http 地址
     *
     * @param cloudFileId
     * @return
     */
    public String getFileHttpUrl(String cloudFileId, String fileId) {
        // 经过实际测试，可以直接做前缀替换
        if (StringUtils.isNotBlank(imgHost)) {
            if (!imgHost.endsWith("/")) {
                imgHost += "/";
            }
            return imgHost + fileId;
        } else {
            // 如果上面的配置访问不了，则走下面的实时替换原则
            String url = String.format(DOWNLOAD_API, wxUserHelper.getAccessToken());
            String uploadAns = HttpRequestHelper.postJson(url, MapUtil.newMap("env", env, "file_list", Arrays.asList(toFileReqParams(cloudFileId))), String.class);
            log.info("获取文件上传地址: {}", uploadAns);
            JSONObject obj = JSONObject.parseObject(uploadAns);
            JSONArray ary = obj.getJSONArray("file_list");
            return ((JSONObject) ary.get(0)).getString("download_url");
        }
    }

    private Map<String, String> toFileReqParams(String cfid) {
        return MapUtil.newMap("fileid", cfid, "max_age", String.valueOf(Integer.MAX_VALUE));
    }
}
